package com.lqjava.tuxiaowang.tuxiaowang.customerapp.app.sdk.wechat;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lqjava.temp.app.confs.props.WXProps;
import com.lqjava.temp.app.entity.response.OTherUserResponse;
import com.lqjava.temp.app.enums.UserTypeEnums;
import com.lqjava.temp.app.sdk.wechat.domain.WXJsSdkDomain;
import com.lqjava.temp.app.sdk.wechat.domain.WXUser;
import com.lqjava.temp.core.utils.UUIDUtil;
import com.xiaoleilu.hutool.crypto.SecureUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Component
public class WechatSDK {
	
	public static final String REDIS_KEY_CODE = "pisen-zd-customer:code:";
	public static final String REDIS_KEY_OPENID = "pisen-zd-customer:openid:";
	
	
	public static final String REDIS_KEY_SK = "pisen-zd-customer:sk:";
	
	
	@Autowired
	RestTemplate wxRestTemplate;
	
	@Autowired
	WXProps props;
	
	@Autowired
	StringRedisTemplate redis;
	
	
	public String getAppId(){
		return props.getAppId();
	}
	
	public String getAppSecret(){
		return props.getAppSecret();
	}
	
	public String getOAuth2URL(String sc){
		String params = sc != null ? "?sc="+sc : null;
		return props.getRedirectUri(params);
	}
	
	
	public String getUIPath(String sc){
		if(StringUtils.isNotBlank(sc)){
			return props.getUiPayPath();
		}else{
			return props.getUiIndexPath();
		}
	}
	
	
	private String getAccessToken(){
		String accessToken = null;
		String appId = getAppId();
		String appSecret = getAppSecret();
		
		String accessTokenURL = props.getAccessTokenURL();
		String url = String.format(accessTokenURL, appId,appSecret);
		
		ResponseEntity<String> forEntity = wxRestTemplate.getForEntity(url, String.class);
		String body = forEntity.getBody();
		JSONObject parseObject = JSON.parseObject(body);
		
		if(parseObject.getBooleanValue("success")){
			accessToken = parseObject.getString("obj");
		}
		return accessToken;
	}
	
	private String getOpenId(String code){
		String key = REDIS_KEY_CODE + code;
		ValueOperations<String, String> ops = redis.opsForValue();
		String openid = ops.get(key);
		if(StringUtils.isBlank(openid)){
			String appId = getAppId();
			String appSecret = getAppSecret();
			String tokenURL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appId+"&secret="+appSecret+"&code="+code+"&grant_type=authorization_code";
			ResponseEntity<String> forEntity = wxRestTemplate.getForEntity(tokenURL, String.class);
			String body = forEntity.getBody();
			openid = JSON.parseObject(body).getString("openid");
			if(openid == null){
				System.err.println(body);
			}
			ops.set(key, openid, 10, TimeUnit.MINUTES);
		}
		
		return openid;
	}
	
	public WXUser getUser(String code){
		WXUser res = null;
		try {
			String openId = getOpenId(code);
			//获取微信用户openId
			String tokenURL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+getAccessToken()+"&openid="+openId+"&lang=zh_CN";
			ResponseEntity<String> forEntity = wxRestTemplate.getForEntity(tokenURL, String.class);
			String body = forEntity.getBody();
			res = JSON.parseObject(body, WXUser.class);
			res.setUserType(UserTypeEnums.WECHART.getCode());
			String sk = UUIDUtil.getUUID();
			res.setSk(sk);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return res;
	}
	
	public WXUser getUserByOpenid(String openid){
		WXUser res = null;
		try {
			//获取微信用户openId
			String tokenURL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+getAccessToken()+"&openid="+openid+"&lang=zh_CN";
			ResponseEntity<String> forEntity = wxRestTemplate.getForEntity(tokenURL, String.class);
			String body = forEntity.getBody();
			res = JSON.parseObject(body, WXUser.class);
			String sk = UUIDUtil.getUUID();
			res.setSk(sk);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return res;
	}
	

    /***
     * 获取jsapiTicket
     * 来源 www.vxzsk.com
     * @return
     */
   public String getJSApiTicket(String accessToken){ 
       //获取token
       String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi";  
       
       ResponseEntity<String> forEntity = wxRestTemplate.getForEntity(urlStr, String.class);
       
       String body = forEntity.getBody();
       JSONObject parseObject = JSON.parseObject(body);
       
       String ticket = null;
       
       if(0 == parseObject.getIntValue("errcode")){
    	   ticket = parseObject.getString("ticket");
       }
       
       return  ticket;
   } 
   
   /**
    * 微信JS SDK 对象获取
    * @param conf 租户配置信息
    * @return
    */
   public WXJsSdkDomain getWXJsSdkDomain(String vname,HttpServletRequest req){
	   
	   WXJsSdkDomain wxJsSdkDomain = null;
	   
	   String accessToken = getAccessToken();
	   
	   if(StringUtils.isNotBlank(accessToken)){
		   
		   String ticket = getJSApiTicket(accessToken);
		   
		   if(StringUtils.isNotBlank(ticket)){
			   
			   wxJsSdkDomain = new WXJsSdkDomain();
			   wxJsSdkDomain.setAccessToken(accessToken);
			   wxJsSdkDomain.setTicket(ticket);
			   wxJsSdkDomain.setAppId(props.getAppId());
			   wxJsSdkDomain.setNonceStr(UUID.randomUUID().toString().replace("-", "").substring(0, 16));//随机字符串  
			   wxJsSdkDomain.setTimestamp(System.currentTimeMillis() / 1000);//时间戳  
			   String url = vname; //ui服务器地址
			   String str = "jsapi_ticket="+ticket+"&noncestr="+wxJsSdkDomain.getNonceStr()+"&timestamp="+wxJsSdkDomain.getTimestamp()+"&url="+url;
			   String signature = DigestUtils.sha1Hex(str);
			   wxJsSdkDomain.setSignature(signature);
		   }
	   }
	   
	   return wxJsSdkDomain;
	   
   }
	
   public void login(OTherUserResponse user,String sk) {
		
		String openId = user.getOpenid();
		if(StringUtils.isNotBlank(openId)){
			String sign = SecureUtil.md5(sk + "_" + user.getOpenid()).toUpperCase();
			ValueOperations<String, String> ops = redis.opsForValue();
			ops.set(sign, JSON.toJSONString(user),60 * 60,TimeUnit.SECONDS);
		}
		
	}
   
	
	
}
